<template>
    <div class="demo-split">
        <Split v-model="split">
            <template #left>
                <div class="demo-split-pane">
                    <el-space>
                        <el-button
                            type="primary"
                            plain
                            icon="Plus"
                            @click="startInsert('')"
                        ></el-button>
                        <el-input
                            placeholder="请输入查询字符"
                            clearable
                            :prefix-icon="Search"
                            v-model="searchPrefix"
                        />
                        <el-button type="primary" icon="Search" @click="search()"></el-button>
                    </el-space>
                    <el-table :data="tableData" style="width: 100%" @row-click="handleRowClick">
                        <el-table-column fixed prop="name" label="Name"/>
                        <el-table-column align="right" label="Operations">
                            <template #default="scope">
                                <el-button link type="primary" size="small" icon="View"
                                           @click="startDetail(scope.row)"></el-button>
                                <el-button link type="primary" size="small" icon="Stamp"
                                           @click="startGrant(scope.row)"></el-button>
                                <el-button link type="primary" size="small" icon="Delete"
                                           @click="startDelete(scope.row)"></el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-dialog
                        title="Add Role"
                        v-model="insertFormShow"
                        width="500"
                    >
                        <el-form ref="insertFormRef" :model="insertForm" :rules="insertFormRules"
                                 :label-width="120" label-position="left">
                            <el-form-item label="name" prop="name">
                                <el-input v-model="insertForm.name" placeholder="请保证 name 唯一"/>
                            </el-form-item>
                        </el-form>
                        <template #footer>
                            <div style="display: flex; justify-content: space-between; align-items: center;">
                                <div>
                                    <el-button @click="insertFormShow = false">取消</el-button>
                                    <el-button type="primary" @click="confirmInsert">确定</el-button>
                                </div>
                            </div>
                        </template>
                    </el-dialog>
                    <el-dialog
                        title="角色授权"
                        v-model="grantFormShow"
                        width="500"
                    >
                        <el-form ref="grantFormRef" :model="grantForm" :rules="grantFormRules" :label-width="120" label-position="left">
                            <el-form-item label="name" prop="name">
                                <el-input :disabled="grantForm.nameDisabled" v-model="grantForm.name"
                                          placeholder="请保证名称唯一, 否则会覆盖同名的链接信息"/>
                            </el-form-item>
                            <el-form-item label="rangeType" prop="rangeType">
                                <el-select v-model="grantForm.rangeType" placeholder="请选择Key范围" style="width: 100%">
                                    <el-option label="仅限指定 Key " value="CURRENT"></el-option>
                                    <el-option label="所有大于 Key " value="BIGGER"></el-option>
                                    <el-option label="前缀为 Key" value="PREFIX"></el-option>
                                    <el-option label="所有 Key" value="ALL"></el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item label="key" prop="key">
                                <el-input v-model="grantForm.key" placeholder="etcd key"/>
                            </el-form-item>
                            <el-form-item label="perm" prop="permType">
                                <el-select v-model="grantForm.permType" placeholder="请选择权限类型" style="width: 100%">
                                    <el-option label="READ" value="READ"></el-option>
                                    <el-option label="WRITE" value="WRITE"></el-option>
                                    <el-option label="READWRITE" value="READWRITE"></el-option>
                                </el-select>
                            </el-form-item>
                        </el-form>
                        <template #footer>
                            <el-space>
                                <el-button @click="grantFormShow = false">取消</el-button>
                                <el-button type="primary" @click="confirmGrant">确定</el-button>
                            </el-space>
                        </template>
                    </el-dialog>
                </div>
            </template>
            <template #right>
                <div class="demo-split-pane">
                    <el-tag size="large" effect="plain" type="warning">Role Name : {{ permNode.name }}</el-tag>
                    <el-table :data="permData" style="width: 100%">
                        <el-table-column prop="name" label="Key"/>
                        <el-table-column prop="permType" align="right" label="permType"/>
                    </el-table>
                </div>
            </template>
        </Split>
    </div>
</template>

<script setup>
import {ref, defineProps, onMounted} from "vue";
import {ElMessage, ElMessageBox} from 'element-plus'
import {auth_role_list, auth_role_add} from "@/api/etcd3.js"
import {Search} from "@element-plus/icons-vue";
import {auth_role_delete, auth_role_get, auth_role_grant, shiftLastChar} from "../../api/etcd3.js";
import {Base64} from "js-base64";
import {Split} from "view-ui-plus";

const formLabelWidth = ref('120px');
const split = ref(0.4)
const props = defineProps({
    connect: {
        type: Object,
        default: {
            name: '默认标题',
            url: 'http://127.0.0.1:2379',
            version: 'v2',
            username: 'root',
            password: '123456'
        }
    }
})

const tableData = ref([
    {
        name: 'Tom',
        read: ['California'],
        write: ['California'],
    }
])

// 授权
// 用户授权
const grantFormShow = ref(false);
const grantFormRef = ref(null)
const grantForm = ref({
    name: '',
    key: '',
    permType: 'READ', //READ、WRITE、READWRITE
    rangeType: 'CURRENT' // CURRENT,BIGGER,PREFIX,ALL
})

const grantFormRules = ref({
    user: [
        {required: true, message: 'Please input role', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 3', trigger: 'blur'},
    ],
    role: [
        {required: true, message: 'Please input role', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 3', trigger: 'blur'},
    ],
})

function startGrant(row) {
    grantFormShow.value = true;
    grantForm.value.name = row.name;
    grantForm.value.nameDisabled = true;
    grantForm.value.key = '';
    grantForm.value.permType = 'READ';
    grantForm.value.rangeType = 'CURRENT';
}

function confirmGrant() {
    grantFormRef.value.validate((valid) => {
        if (valid) {
            // 关闭弹框
            grantFormShow.value = false;
            let url = props.connect.url;
            // 执行新增逻辑
            let key = Base64.encode(grantForm.value.key);
            let range_end = null;
            if (grantForm.value.rangeType === 'BIGGER') {
                range_end = Base64.encode('\0');
            }
            if (grantForm.value.rangeType === 'PREFIX') {
                range_end = Base64.encode(shiftLastChar(grantForm.value.key));
            }
            if (grantForm.value.rangeType === 'ALL') {
                key = Base64.encode('\0');
                range_end = Base64.encode('\0');
            }
            let grant = {
                "name": grantForm.value.name,
                "perm": {
                    "key": key,
                    "permType": grantForm.value.permType,
                    "range_end": range_end
                }
            };
            auth_role_grant(url, grant)
                .then(res => {
                    ElMessage.success('auth_user_grant ' + 'success');
                    // 重新查询
                    search();
                })
                .catch(error => {
                    let message = error.response.data.message;
                    ElMessage.error('auth_user_grant ' + message);
                });

        }
    });
}

// 新增
const insertFormShow = ref(false);
const insertFormRef = ref(null)
const insertForm = ref({
    name: ''
})
const insertFormRules = ref({
    name: [
        {required: true, message: 'Please input ID', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 1', trigger: 'blur'},
    ]
})

function startInsert() {
    insertFormShow.value = true;
    insertForm.value.name = null;
}

function confirmInsert() {
    insertFormRef.value.validate((valid) => {
        if (valid) {
            // 关闭弹框
            insertFormShow.value = false;
            // 执行新增逻辑
            let url = props.connect.url;
            let data = {
                name: insertForm.value.name
            };
            auth_role_add(url, data)
                .then(res => {
                    ElMessage.success('auth_role_add ' + 'success');
                    // 重新查询
                    search();
                })
                .catch(error => {
                    let message = error.response.data.message;
                    ElMessage.error('auth_role_add ' + message);
                });

        }
    });
}

// 删除
function startDelete(row) {
    ElMessageBox.confirm(
        'Permanently delete the node. Continue?',
        'Warning',
        {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
        }
    )
        .then(() => {
            confirmDelete(row);
        })
        .catch(() => {
            // do nothing
        })
}

function confirmDelete(row) {
    let url = props.connect.url;
    let name = row.name;
    auth_role_delete(url, name)
        .then(response => {
            search();
        })
        .catch(error => {
            let message = error.response.data.message;
            ElMessage.error('kv_delete ' + message);
        });
}

// 详情信息
const permNode = ref({})
const permData = ref([
    {
        "permType": "READWRITE",
        "key": "YWFh"
    }
])
const permPrefix = ref(null)

const handleRowClick = (row, column, event) => {
    startDetail(row);
};

function startDetail(row) {
    permNode.value = row;
    permData.value = [];
    permPrefix.value = null;
    permSearch(row);
}

function permSearch(row) {
    let url = props.connect.url;
    auth_role_get(url, row.name)
        .then(res => {
            let result = res.data;
            if (!!result.perm && Array.isArray(result.perm) && result.perm.length > 0) {
                for (let i = 0; i < result.perm.length; i++) {
                    let item = result.perm[i];
                    item.name = Base64.decode(item.key);
                    if (!!permPrefix.value) {
                        if (item.name.includes(permPrefix.value)) {
                            permData.value.push(item);
                        }
                    } else {
                        permData.value.push(item);
                    }
                }
            }
        })
        .catch(error => {
            let message = error.response.data.message;
            ElMessage.error('auth_role_get ' + message);
        })
}

// 查询
const searchPrefix = ref(null)
const search = () => {
    let con = {};
    let temp = props.connect;
    console.log(props)
    console.log(props.connect)
    con.url = props.connect.url;
    con.version = props.connect.version;
    let auth = {};
    auth.username = props.connect.username;
    auth.password = props.connect.password;
    auth_role_list(con.url, con.version, auth)
        .then(res => {
            console.log(res);
            tableData.value = [];
            let roles = [];
            let items = res.data.roles;
            if (Array.isArray(items)) {
                for (let i = 0; i < items.length; i++) {
                    // nodes[i].hasChildren =false;
                    // nodes[i].children = []
                    let u = {};
                    u.name = items[i];
                    if (!!searchPrefix.value) {
                        if (u.name.includes(searchPrefix.value)) {
                            roles.push(u);
                        } else {
                            continue;
                        }
                    } else {
                        roles.push(u);
                    }
                }
                roles.sort((a, b) => {
                    return a.name.localeCompare(b.name);
                });
                tableData.value = roles;
            }
        })
        .catch(error => {
            ElMessage.error('UsersEtcd:' + error.message)
        })
}
onMounted(() => {
    search();
})

</script>
<style>
.demo-split {
    height: 90vh;
    width: 100%;
    margin: 2px;
    border: 1px solid #dcdee2;
}

.demo-split-pane {
    height: 100%;
    padding: 10px;
}
</style>